// API错误处理工具

// 错误类型枚举
export const ErrorType = {
  NETWORK_ERROR: 'NETWORK_ERROR',
  SERVER_ERROR: 'SERVER_ERROR',
  CLIENT_ERROR: 'CLIENT_ERROR',
  AUTH_ERROR: 'AUTH_ERROR',
  TIMEOUT_ERROR: 'TIMEOUT_ERROR',
  UNKNOWN_ERROR: 'UNKNOWN_ERROR'
}

// 错误状态码映射
export const ErrorStatusMap = {
  400: '请求参数错误',
  401: '未授权，请重新登录',
  403: '拒绝访问',
  404: '请求的资源不存在',
  405: '请求方法不支持',
  408: '请求超时',
  413: '请求体过大',
  415: '不支持的媒体类型',
  500: '服务器内部错误',
  501: '服务器未实现该功能',
  502: '网关错误',
  503: '服务不可用',
  504: '网关超时'
}

// 处理API错误
export const handleApiError = (error) => {
  // 网络错误
  if (!error.response) {
    if (error.request) {
      // 请求已发送但未收到响应
      return {
        type: ErrorType.NETWORK_ERROR,
        message: '网络连接失败，请检查您的网络设置',
        status: null,
        originalError: error
      }
    }
    // 其他错误
    return {
      type: ErrorType.UNKNOWN_ERROR,
      message: '未知错误',
      status: null,
      originalError: error
    }
  }
  
  const { status, data } = error.response
  
  // 超时错误
  if (error.code === 'ECONNABORTED') {
    return {
      type: ErrorType.TIMEOUT_ERROR,
      message: '请求超时，请稍后再试',
      status: status,
      originalError: error
    }
  }
  
  // 认证错误
  if (status === 401) {
    // 可以在这里处理登出逻辑
    // store.dispatch('auth/logout')
    return {
      type: ErrorType.AUTH_ERROR,
      message: data?.message || ErrorStatusMap[status] || '认证失败',
      status: status,
      originalError: error
    }
  }
  
  // 客户端错误
  if (status >= 400 && status < 500) {
    return {
      type: ErrorType.CLIENT_ERROR,
      message: data?.message || ErrorStatusMap[status] || '请求错误',
      status: status,
      originalError: error
    }
  }
  
  // 服务器错误
  if (status >= 500) {
    return {
      type: ErrorType.SERVER_ERROR,
      message: data?.message || ErrorStatusMap[status] || '服务器错误',
      status: status,
      originalError: error
    }
  }
  
  // 其他错误
  return {
    type: ErrorType.UNKNOWN_ERROR,
    message: '未知错误',
    status: status,
    originalError: error
  }
}

// 显示错误提示
export const showApiError = (error, showToast = null) => {
  const errorInfo = handleApiError(error)
  
  // 如果提供了showToast函数，则使用它显示错误
  if (typeof showToast === 'function') {
    showToast(errorInfo.message)
  }
  
  // 打印详细错误信息到控制台
  console.error('API Error:', errorInfo)
  
  return errorInfo
}

// API请求配置
export const apiConfig = {
  baseURL: process.env.VUE_APP_API_BASE_URL || '/api',
  timeout: 30000, // 30秒超时
  headers: {
    'Content-Type': 'application/json'
  },
  retry: {
    count: 3,
    delay: 1000,
    statuses: [408, 429, 500, 502, 503, 504]
  }
}

// API请求重试
export const retryRequest = async (request, retries = 0) => {
  try {
    const response = await request()
    return response
  } catch (error) {
    const { status } = error.response || {} 
    const shouldRetry = retries < apiConfig.retry.count && 
                       apiConfig.retry.statuses.includes(status)
    
    if (shouldRetry) {
      // 等待一段时间后重试
      await new Promise(resolve => setTimeout(resolve, apiConfig.retry.delay * (retries + 1)))
      return retryRequest(request, retries + 1)
    }
    
    // 不需要重试时抛出错误
    throw error
  }
}

// API缓存管理
export const ApiCache = {
  // 缓存存储
  _cache: new Map(),
  
  // 默认缓存时间（毫秒）
  _defaultTTL: 5 * 60 * 1000, // 5分钟
  
  // 设置缓存
  set(key, data, ttl = this._defaultTTL) {
    const expiry = Date.now() + ttl
    this._cache.set(key, { data, expiry })
    // 清理过期缓存
    this._cleanup()
  },
  
  // 获取缓存
  get(key) {
    this._cleanup()
    const item = this._cache.get(key)
    
    if (!item) {
      return null
    }
    
    // 检查是否过期
    if (Date.now() > item.expiry) {
      this._cache.delete(key)
      return null
    }
    
    return item.data
  },
  
  // 删除缓存
  delete(key) {
    this._cache.delete(key)
  },
  
  // 清除所有缓存
  clear() {
    this._cache.clear()
  },
  
  // 获取缓存键
  getCacheKey(url, params = {}) {
    // 将参数排序并字符串化，以确保相同的参数顺序生成相同的键
    const sortedParams = Object.keys(params)
      .sort()
      .reduce((acc, key) => {
        acc[key] = params[key]
        return acc
      }, {})
    
    return `${url}_${JSON.stringify(sortedParams)}`
  },
  
  // 清理过期缓存
  _cleanup() {
    const now = Date.now()
    for (const [key, item] of this._cache.entries()) {
      if (now > item.expiry) {
        this._cache.delete(key)
      }
    }
  }
}

// API请求统计
export const ApiStats = {
  requests: 0,
  failures: 0,
  successes: 0,
  
  reset() {
    this.requests = 0
    this.failures = 0
    this.successes = 0
  },
  
  incrementRequests() {
    this.requests++
  },
  
  incrementSuccesses() {
    this.successes++
  },
  
  incrementFailures() {
    this.failures++
  },
  
  getStats() {
    return {
      requests: this.requests,
      failures: this.failures,
      successes: this.successes,
      successRate: this.requests > 0 ? (this.successes / this.requests * 100).toFixed(2) + '%' : '0%'
    }
  }
}

// 请求参数序列化
export const serializeParams = (params) => {
  if (!params || Object.keys(params).length === 0) {
    return ''
  }
  
  const queryParams = new URLSearchParams()
  
  Object.entries(params).forEach(([key, value]) => {
    // 处理数组参数
    if (Array.isArray(value)) {
      value.forEach(item => {
        queryParams.append(`${key}[]`, item)
      })
    } 
    // 处理对象参数
    else if (typeof value === 'object' && value !== null) {
      queryParams.append(key, JSON.stringify(value))
    } 
    // 处理基本类型参数
    else if (value !== undefined && value !== null) {
      queryParams.append(key, value)
    }
  })
  
  return queryParams.toString()
}

// 文件上传进度处理
export const createUploadProgressHandler = (callback) => {
  return (progressEvent) => {
    if (progressEvent.lengthComputable) {
      const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
      callback(percentCompleted)
    }
  }
}

// 下载进度处理
export const createDownloadProgressHandler = (callback) => {
  return (progressEvent) => {
    if (progressEvent.lengthComputable) {
      const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
      callback(percentCompleted)
    }
  }
}

// API响应数据格式化
export const formatApiResponse = (response) => {
  // 假设API响应格式为 { code, message, data } 或直接返回数据
  if (response && typeof response === 'object') {
    // 如果响应包含code和data字段
    if ('code' in response && 'data' in response) {
      // 成功状态码（根据实际API定义调整）
      const successCodes = [200, 0, '200', '0', 'success']
      
      const isSuccess = successCodes.includes(response.code)
      
      return {
        success: isSuccess,
        data: response.data,
        message: response.message || (isSuccess ? '操作成功' : '操作失败'),
        raw: response
      }
    }
    // 直接返回的响应数据
    return {
      success: true,
      data: response,
      message: '操作成功',
      raw: response
    }
  }
  
  // 无效响应
  return {
    success: false,
    data: null,
    message: '无效的响应数据',
    raw: response
  }
}

// API请求日志记录
export const logApiRequest = (method, url, params, data) => {
  if (process.env.NODE_ENV === 'development') {
    console.log(`[API Request] ${method.toUpperCase()} ${url}`)
    
    if (params) {
      console.log('  Params:', params)
    }
    
    if (data) {
      console.log('  Data:', data)
    }
  }
}

// API响应日志记录
export const logApiResponse = (method, url, response, duration) => {
  if (process.env.NODE_ENV === 'development') {
    console.log(`[API Response] ${method.toUpperCase()} ${url} (${duration}ms)`)
    console.log('  Response:', response)
  }
}

// API错误日志记录
export const logApiError = (method, url, error) => {
  console.error(`[API Error] ${method.toUpperCase()} ${url}`)
  console.error('  Error:', error)
}

// 处理认证令牌
export const authTokenUtils = {
  // 获取令牌
  getToken() {
    return localStorage.getItem('authToken') || sessionStorage.getItem('authToken')
  },
  
  // 设置令牌
  setToken(token, remember = false) {
    if (remember) {
      localStorage.setItem('authToken', token)
    } else {
      sessionStorage.setItem('authToken', token)
    }
  },
  
  // 清除令牌
  clearToken() {
    localStorage.removeItem('authToken')
    sessionStorage.removeItem('authToken')
  },
  
  // 检查令牌是否存在
  hasToken() {
    return !!this.getToken()
  },
  
  // 解析令牌（JWT格式）
  parseToken(token = null) {
    try {
      token = token || this.getToken()
      if (!token) return null
      
      const parts = token.split('.')
      if (parts.length !== 3) return null
      
      const payload = JSON.parse(atob(parts[1]))
      return {
        header: JSON.parse(atob(parts[0])),
        payload: payload,
        signature: parts[2],
        expiresAt: new Date(payload.exp * 1000),
        issuedAt: new Date(payload.iat * 1000)
      }
    } catch (error) {
      console.error('解析令牌失败:', error)
      return null
    }
  },
  
  // 检查令牌是否过期
  isTokenExpired(token = null) {
    const parsedToken = this.parseToken(token)
    if (!parsedToken || !parsedToken.expiresAt) return true
    
    return parsedToken.expiresAt.getTime() < Date.now()
  }
}

// API请求取消控制器
export const createCancelableRequest = () => {
  const controller = new AbortController()
  const signal = controller.signal
  
  return {
    signal,
    cancel: () => controller.abort()
  }
}

// 批量API请求处理
export const batchApiRequests = async (requests, { concurrent = 5, onProgress = null } = {}) => {
  const results = []
  const queue = [...requests]
  const activeRequests = new Set()
  
  const executeNext = async () => {
    if (queue.length === 0) return
    
    const request = queue.shift()
    const { method, url, data, options } = request
    
    try {
      const startTime = Date.now()
      activeRequests.add(request)
      
      // 执行请求
      const response = await window.axios[method](url, data, {
        ...options,
        signal: createCancelableRequest().signal
      })
      
      const duration = Date.now() - startTime
      
      results.push({
        request,
        response,
        success: true,
        duration
      })
      
      // 更新进度
      if (typeof onProgress === 'function') {
        onProgress({
          completed: results.length,
          total: requests.length,
          progress: (results.length / requests.length) * 100
        })
      }
    } catch (error) {
      results.push({
        request,
        error: handleApiError(error),
        success: false
      })
      
      // 更新进度
      if (typeof onProgress === 'function') {
        onProgress({
          completed: results.length,
          total: requests.length,
          progress: (results.length / requests.length) * 100,
          error: true
        })
      }
    } finally {
      activeRequests.delete(request)
      await executeNext()
    }
  }
  
  // 启动并发请求
  const promises = []
  for (let i = 0; i < Math.min(concurrent, requests.length); i++) {
    promises.push(executeNext())
  }
  
  await Promise.all(promises)
  
  return results
}